package ldh.im.fxgui.controller.handler;

import javafx.beans.Observable;
import javafx.beans.binding.DoubleBinding;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.geometry.Orientation;
import javafx.scene.Node;
import javafx.scene.control.ScrollBar;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import ldh.im.fxbase.pojo.DbMessage;
import org.fxmisc.flowless.Cell;
import org.fxmisc.flowless.VirtualFlow;
import org.fxmisc.flowless.VirtualizedScrollPane;

import java.util.List;

public class SendMessageVirtualFlowHandler implements SendMessageHandler {

    private ObservableList<DbMessage> items = FXCollections.observableArrayList();
    private VirtualFlow<DbMessage, ?> messageList;

    public Node createMessagePaneNode() {
        messageList = VirtualFlow.createVertical(items, m->{
            return Cell.wrapNode(createMessagePane(m));
        });

//        ScrollBar scrollBar = new ScrollBar();
//        scrollBar.setOrientation(Orientation.VERTICAL);
//
//        HBox hBox = new HBox(messageList, scrollBar);
//        HBox.setHgrow(messageList, Priority.ALWAYS);
//        scrollBar.maxProperty().bind(messageList.totalHeightEstimateProperty());
//        scrollBar.valueProperty().addListener(l->{
//            messageList.scrollYToPixel(scrollBar.getValue());
//        });
//        messageList.estimatedScrollYProperty().addListener(l->{
//            scrollBar.setValue(messageList.lengthOffsetEstimateProperty().getValue());
//        });
//        setupUnitIncrement(scrollBar);
        VirtualizedScrollPane virtualizedScrollPane = new VirtualizedScrollPane<>(messageList);

        return virtualizedScrollPane;
    }

    @Override
    public void addMessage(DbMessage message) {
        items.add(message);
        messageList.show(items.size());
    }

    @Override
    public void addMessages(List<DbMessage> messages) {
        items.addAll(messages);
        messageList.show(items.size());
    }

    @Override
    public ObservableList<DbMessage> getItems() {
        return items;
    }

    private static void setupUnitIncrement(final ScrollBar bar) {
        bar.unitIncrementProperty().bind(new DoubleBinding() {
            {
                this.bind(new Observable[]{bar.maxProperty(), bar.visibleAmountProperty()});
            }

            protected double computeValue() {
                double max = bar.getMax();
                double visible = bar.getVisibleAmount();
                return max > visible ? 16.0D / (max - visible) * max : 0.0D;
            }
        });
    }
}
